package com.spzx.cart.service.impl;

import com.spzx.cart.api.domain.CartInfo;
import com.spzx.cart.service.CartInfoService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.context.SecurityContextHolder;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.model.ProductSku;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class CartInfoServiceImpl implements CartInfoService {
   @Autowired
   private RedisTemplate redisTemplate;

   @Autowired
   private RemoteProductService remoteProductService;

    @Override
    //将指定商品ID对应数量加入到购物车
    public void addToCart(Long skuId, Integer num) {
        //1.判断购物车中是否有该商品
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = this.getCartKey(userId);
        String field = skuId.toString();
        //写法一
//        Boolean exists = redisTemplate.opsForHash().hasKey(cartKey, field);
        BoundHashOperations<String,String,CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        Boolean exists = hashOps.hasKey(field);
        //2.如果商品存在,则更新数量 单品数量上限99
        if(exists){
            CartInfo cartInfo = (CartInfo) redisTemplate.opsForHash().get(cartKey, field);
            Integer skuNum = cartInfo.getSkuNum();
            cartInfo.setSkuNum(skuNum+num>99?99:skuNum+num);
            cartInfo.setCreateTime(new Date());
//            redisTemplate.opsForHash().put(cartKey,field,cartInfo);
            hashOps.put(field,cartInfo);
        }else{
            //3.如果商品不存在,则构建购物车商品对象,最多加购商品数量50,并保存到购物车中
            //3.1 业务校验
//            Long count = redisTemplate.opsForHash().size(cartKey);
            Long count = hashOps.size();
            if(count>50){
                throw new RuntimeException("最多只能加入50个商品");
            }
            //3.2 远程调用商品服务获取商品信息
            //代理对象在执行
            R<ProductSku> r= remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
            if(r.getCode() !=200){
                throw  new ServiceException("远程商品服务调用失败,原因:"+r.getMsg());
            }
            ProductSku productSku = r.getData();
            //3.3 构建购物车商品对象
            CartInfo cartInfo = new CartInfo();
            cartInfo.setUserId(userId);
            cartInfo.setSkuId(productSku.getId());
            cartInfo.setCartPrice(productSku.getSalePrice());
            cartInfo.setSkuPrice(productSku.getSalePrice());
            cartInfo.setSkuNum(num>99?99:num);
            cartInfo.setThumbImg(productSku.getThumbImg());
            cartInfo.setSkuName(productSku.getSkuName());
            cartInfo.setCreateTime(new Date());


            //3.4 将购物车商品写入Redis
//            redisTemplate.opsForHash().put(cartKey,field,cartInfo);
            hashOps.put(field,cartInfo);
        }
    }



    private  String getCartKey(Long userId){
        //定义key user:userId:cart
        return "user:cart:"+ userId;
    }

    @Override
    public List<CartInfo> cartList() {
        //1.确定当前用户购物车的Key
        String cartKey = this.getCartKey(SecurityContextHolder.getUserId());
        //2.获取购物车Hash结构中Value列表对应就是购物车商品列表
        BoundHashOperations<String,String,CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();
        //3.如果有值,按照加入购物车时间进行降序,并返回
if(!ObjectUtils.isEmpty(cartInfoList)){
    List<CartInfo> collect = cartInfoList.stream()
            .sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()))
            .collect(Collectors.toList());
    return collect;
}
        return null;
    }

    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        //1.确定当前用户购物车的Key
        String cartKey = this.getCartKey(SecurityContextHolder.getUserId());
        //2.确定购物车上的商品field
        String field = skuId.toString();
        //3.获取购物车中的商品
       CartInfo  cartInfo = (CartInfo) redisTemplate.opsForHash().get(cartKey, field);
        //4.更新购物车商品选中状态
        cartInfo.setIsChecked(isChecked);
        redisTemplate.opsForHash().put(cartKey,field,cartInfo);
    }

    @Override
    public void allCheckCart(Integer isChecked) {
        String cartKey = this.getCartKey(SecurityContextHolder.getUserId());
        BoundHashOperations<String,String,CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();
        if(!ObjectUtils.isEmpty(cartInfoList)){
            cartInfoList.forEach(cartInfo -> {
                cartInfo.setIsChecked(isChecked);
                hashOps.put(cartInfo.getSkuId().toString(),cartInfo);
            });
        }
    }

    @Override
    public void deleteCart(Long skuId) {
        String cartKey = this.getCartKey(SecurityContextHolder.getUserId());
        BoundHashOperations<String,String,CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        String field = skuId.toString();
        Boolean exists = hashOps.hasKey(field);
        if(exists){
            hashOps.delete(field);
        }
    }

    @Override
    public void clearCart() {
        String cartKey = this.getCartKey(SecurityContextHolder.getUserId());
       redisTemplate.delete(cartKey);
    }

    @Override
    public List<CartInfo> getCartCheckedList() {
        String cartKey = this.getCartKey(SecurityContextHolder.getUserId());
        BoundHashOperations<String,String,CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();
        if(!ObjectUtils.isEmpty(cartInfoList)){
            List<CartInfo> cartCheckedList = cartInfoList.stream().filter(cartInfo -> cartInfo.getIsChecked() == 1
            ).collect(Collectors.toList());
            return cartCheckedList;
        }
        return null;
    }
}
